package com.aishua.aishuawallet.mina;


import android.content.Context;
import android.util.Log;


import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.lang.ref.WeakReference;
import java.net.InetSocketAddress;

import app.socketlib.com.library.utils.LogUtil;

/**
 * Created by aishua on 2018/8/22.
 */

public class ConnectionManager {

    private static final String TAG = "ConnectionManager-";
    private ConnectionConfig mConfig;
    private WeakReference<Context> mContext;
    private MinaResultLIstener minaResultLIstener;
    private NioSocketConnector mConnection;
    private IoSession mSession;
    private InetSocketAddress mAddress;

    public ConnectionManager(ConnectionConfig config,MinaResultLIstener minaResultLIstener) {

        this.mConfig = config;
        this.mContext = new WeakReference<>(config.getContext());
        this.minaResultLIstener = minaResultLIstener;
        init();
    }

    /**
     * 30秒后超时
     */
    private static final int IDELTIMEOUT =1;
    /**
     * 15秒发送一次心跳包
     */
    private static final int HEARTBEATRATE = 3;

    private static final String HEARTBEATREQUEST =  "0000002003111000000000000000000000000000";
    private static final String HEARTBEATRESPONSE = "0000002003111001000000000000000000000000";

    private void init() {

        mAddress = new InetSocketAddress(mConfig.getIp(), mConfig.getPort());
        mConnection = new NioSocketConnector();
        mConnection.getSessionConfig().setReadBufferSize(mConfig.getReadBufferSize());
        mConnection.getFilterChain().addLast("logging", new LoggingFilter());

        mConnection.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
//        /** 主角登场 */
        KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
        KeepAliveRequestTimeoutHandler heartBeatHandler = new KeepAliveRequestTimeoutHandlerImpl();
        KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,KeepAliveRequestTimeoutHandler.LOG);

        /** 是否回发 */
        heartBeat.setForwardEvent(true);
//        /** 发送频率 */
        heartBeat.setRequestInterval(HEARTBEATRATE);
        heartBeat.setRequestTimeout(IDELTIMEOUT);
        mConnection.getSessionConfig().setKeepAlive(true);
        mConnection.getFilterChain().addLast("heartbeat", heartBeat);
        mConnection.setHandler(new DefaultHandler(mContext.get()));
        mConnection.setDefaultRemoteAddress(mAddress);


    }

    /**
     * 与服务器连接
     * @return
     */
    public IoSession connnect() {

             Log.e("tag", "准备连接");

            ConnectFuture future = mConnection.connect();
            future.awaitUninterruptibly();
            mSession = future.getSession();

        return mSession;

    }
    /**
     * 断开连接
     */
    public void disContect() {

        mConnection.dispose();
        mConnection = null;
        mSession = null;
        mAddress = null;
        mContext = null;
        Log.e("tag", "断开连接");
    }

    private class DefaultHandler extends IoHandlerAdapter {

        private Context mContext;

        private DefaultHandler(Context context) {

            this.mContext = context;

        }

        @Override
        public void sessionOpened(IoSession session) throws Exception {

            super.sessionOpened(session);
        }

        @Override
        public void messageReceived(IoSession session, Object message){

            Log.e("messageReceived", "接收到服务器端消息：" + message.toString());
            minaResultLIstener.messageReceived(session,message);
        }


        @Override
        public void messageSent(IoSession session, Object message) throws Exception {
            super.messageSent(session, message);

            Log.e("messageSent", "发送到服务器端消息：" + message.toString());

        }

        @Override
        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
            super.exceptionCaught(session, cause);

            Log.e("exceptionCaught", "客户端异常：" + cause.toString());
            minaResultLIstener.exceptionCaught(session,cause);

        }
    }
    private class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {

        /*
         * (non-Javadoc)
         *
         * @see
         * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getRequest
         * (org.apache.mina.core.session.IoSession)
         */
        @Override
        public Object getRequest(IoSession session) {

            Log.e("tag", "getRequest：" + session.toString());
            return HEARTBEATREQUEST;
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getResponse
         * (org.apache.mina.core.session.IoSession, java.lang.Object)
         */
        @Override
        public Object getResponse(IoSession session, Object request) {

            Log.e("tag", "getResponse：" + request.toString());

            return null;
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isRequest
         * (org.apache.mina.core.session.IoSession, java.lang.Object)
         */
        @Override
        public boolean isRequest(IoSession session, Object message) {
            Log.e("isRequest:" , message.toString());

            if(message.toString().equals(HEARTBEATRESPONSE)) {

                LogUtil.w("客户端进入idle状态,向服务器发送心跳包:" + HEARTBEATREQUEST);
                return true;

            } else {

                return false;
            }
//            return false;
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isResponse
         * (org.apache.mina.core.session.IoSession, java.lang.Object)
         */
        @Override
        public boolean isResponse(IoSession session, Object message) {

             String msg = (String) message;
            Log.e("isResponse:",msg +"msg.equals(HEARTBEATRESPONSE)："+msg.equals(HEARTBEATRESPONSE) );
            if(msg.toString().equals(HEARTBEATREQUEST)) {

                Log.e("服务器回复心跳包:" , message.toString());

                return true;
            } else {

                return false;
           }
        }

    }

    /***
     * @ClassName: KeepAliveRequestTimeoutHandlerImpl
     * @Description: 当心跳超时时的处理，也可以用默认处理 这里like
     */
    private  class KeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler {

        /*
         * (non-Javadoc)
         *
         * @seeorg.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler#
         * keepAliveRequestTimedOut
         * (org.apache.mina.filter.keepalive.KeepAliveFilter,
         * org.apache.mina.core.session.IoSession)
         */
        @Override
        public void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception {

            LOG.keepAliveRequestTimedOut(filter,session);
        }

    }


}
